﻿using ApiManage.Models.MongoMappings.Project;
using ApiManage.Models.RequestModels;
using ApiManage.Svc.Filter;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using Rhonin.Common.Entity.Exception;
using Rhonin.Common.Entity.Page;
using Rhonin.Common.Extentions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ApiManage.Applications.Mongo.Project;
using ApiManage.Service.Mongo.Project;
using Rhonin.Common.Entity.Api;
using ApiManage.Models.ResultModels;
using Newtonsoft.Json;
using ApiManage.Core.Utils;
using ApiManage.Models.RequestModels.Project.Interface;
using ApiManage.Service.Mongo.Sys;

namespace ApiManage.Svc.Controllers.Project
{
    /// <inheritdoc />
    /// <summary>
    /// 模块列表
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class InterfaceController : BaseController
    {
        private readonly IInterfaceInfoService _interfaceService;
        private readonly IInterfaceInfoQueryService _interfaceQueryService;
        private readonly IProjectQueryService _projectQueryService;
        private readonly IModulesQueryService _moduleQueryService;
        private readonly ISysUserQueryService _sysUserQueryService;
        /// <summary>
        /// 
        /// </summary>
        public InterfaceController(IInterfaceInfoService interfaceService,
            IInterfaceInfoQueryService interfaceQueryService,
            IProjectQueryService projectQueryService,
            IModulesQueryService moduleQueryService,
            ISysUserQueryService sysUserQueryService)
        {
            _interfaceService = interfaceService;
            _interfaceQueryService = interfaceQueryService;
            _projectQueryService = projectQueryService;
            _moduleQueryService = moduleQueryService;
            _sysUserQueryService = sysUserQueryService;
        }
        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [Route("GetPage"), HttpGet, CheckLogin]
        public ApiResult<PageResult<InterfaceInfo>> GetPage(string name, int pageIndex, int pageSize)
        {
            var param = new QueryPage
            {
                PageIndex = pageIndex,
                PageSize = pageSize
            };
            Expression<Func<InterfaceInfo, bool>> where = o => o.Status != "Delete";
            where = where.AndIf(o => o.Name.Contains(name), name.IsNotEmpty());
            var list = _interfaceQueryService.GetList(where);
            var page = new PageResult<InterfaceInfo>
            {
                TotalCount = list.Count,
                Items = list.OrderByDescending(o => o.CreateTime).Skip(param.Skip).Take(param.Limit),
                PageParameter = param
            };
            return CreateResult(page);
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("Save"), HttpPost, CheckLogin]
        public ApiResult Save(InterfaceInfoExtend param)
        {
            if (string.IsNullOrEmpty(param.Name))
                throw new ApiException("名称不能为空");
            if (string.IsNullOrEmpty(param.ModuleId))
                throw new ApiException("所属模块不能为空");
            if (param.Id.IsNullOrEmpty())
            {
                _interfaceService.Insert(new InterfaceInfo
                {
                    ModuleId = param.ModuleId,
                    Name = param.Name,
                    Description = param.Description,
                    Url = param.Url,
                    Method = param.Method,
                    Version = param.Version,
                    Developers = param.Developers,
                    DockingPeople = param.DockingPeople,
                    ServersProgress = param.ServersProgress,
                    ClientProgress = param.ClientProgress,
                    ResponseContentType = param.ResponseContentType,
                    RequestHeader = param.RequestHeader,
                    RequestOther = param.RequestOther,
                    ResponseParam = param.ResponseParam,
                    ResponseParamDesc = param.ResponseParamDesc,
                    RequestContentType = param.RequestContentType,
                    RequestParam = param.RequestParam,
                    RequestParamDesc = param.RequestParamDesc,
                    ResponseSuccExam = param.ResponseSuccExam,
                    ResponseErrExam = param.ResponseErrExam,
                    Host = param.Host,
                    Sort = param.Sort,
                    UseJwt = param.UseJwt,
                    CreateUser = UserId,
                    Status = param.Status
                });
            }
            else
            {
                _interfaceService.Update(u => u.Id == new ObjectId(param.Id), Builders<InterfaceInfo>.Update
                    .Set("ModuleId", param.ModuleId)
                    .Set("Name", param.Name)
                    .Set("Description", param.Description)
                    .Set("Url", param.Url)
                    .Set("Method", param.Method)
                    .Set("Version", param.Version)
                    .Set("Developers", UserId)
                    .Set("DockingPeople", param.DockingPeople)
                    .Set("ServersProgress", param.ServersProgress)
                    .Set("ClientProgress", param.ClientProgress)
                    .Set("ResponseContentType", param.ResponseContentType)
                    .Set("RequestHeader", param.RequestHeader)
                    .Set("RequestOther", param.RequestOther)
                    .Set("ResponseParam", param.ResponseParam)
                    .Set("ResponseParamDesc", param.ResponseParamDesc)
                    .Set("RequestContentType", param.RequestContentType)
                    .Set("RequestParam", param.RequestParam)
                    .Set("RequestParamDesc", param.RequestParamDesc)
                    .Set("ResponseSuccExam", param.ResponseSuccExam)
                    .Set("ResponseErrExam", param.ResponseErrExam)
                    .Set("Host", param.Host)
                    .Set("Sort", param.Sort)
                    .Set("Status", param.Status)
                    .Set("UseJwt", param.UseJwt));
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("Remove"), HttpPost, CheckLogin]
        public ApiResult Remove(IdParam param)
        {
            try
            {
                _interfaceService.Delete(u => u.Id == new ObjectId(param.Id));
            }
            catch (Exception ex)
            {
                return CreateError(ex.Message);
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 复制为新接口
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("CopyNewVersion"), HttpPost, CheckLogin]
        public ApiResult CopyNewVersion(CopyNewVersionParam param)
        {
            try
            {
                var interfaceInfo = _interfaceQueryService.Get(o => o.Id == new ObjectId(param.Id));
                if (interfaceInfo.Version.Equals(param.Version))
                    throw new ApiException("版本号不能相同");
                interfaceInfo.Id = new ObjectId();
                interfaceInfo.Version = param.Version;
                _interfaceService.Insert(interfaceInfo);
            }
            catch (Exception ex)
            {
                return CreateError(ex.Message);
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 复制为新接口
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("UpdateProgress"), HttpPost, CheckLogin]
        public ApiResult UpdateProgress(ProgressParam param)
        {
            try
            {
                if (param.Type == "servers")
                {
                    _interfaceService.Update(u => u.Id == new ObjectId(param.Id), Builders<InterfaceInfo>.Update
                        .Set("Developers", param.UserId)
                        .Set("ServersProgress", param.Progress));
                }
                else
                {
                    _interfaceService.Update(u => u.Id == new ObjectId(param.Id), Builders<InterfaceInfo>.Update
                        .Set("DockingPeople", param.UserId)
                        .Set("ClientProgress", param.Progress));
                }
            }
            catch (Exception ex)
            {
                return CreateError(ex.Message);
            }
            return CreateSuccess();
        }
        /// <summary>
        /// 获取接口信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Route("GetInfo"), HttpGet, CheckLogin]
        public ApiResult<InterfaceInfo> GetInfo(string id)
        {
            var interfaceInfo = _interfaceQueryService.Get(o => o.Id == new ObjectId(id));
            var developers = interfaceInfo.Developers != null ? _sysUserQueryService.Get(o => o.Id == new ObjectId(interfaceInfo.Developers)) : null;
            var dockingPeople = interfaceInfo.DockingPeople != null ? _sysUserQueryService.Get(o => o.Id == new ObjectId(interfaceInfo.DockingPeople)) : null;
            interfaceInfo.DevelopersName = developers?.UserName;
            interfaceInfo.DockingPeopleName = dockingPeople?.UserName;
            return CreateResult(interfaceInfo);
        }

        /// <summary>
        /// 获取接口树
        /// </summary>
        /// <returns></returns>
        [Route("GetInterfaceTree"), HttpGet, CheckLogin]
        public ApiResult<List<InterfaceTree>> GetInterfaceTree()
        {
            var project = _projectQueryService.GetList(o => o.Status != "Delete" && o.User.Contains(UserId)).Select(o => new InterfaceTree
            {
                Id = o.Id.ToString(),
                Name = o.Name,
                Type = "project",
                Children = _moduleQueryService.GetList(m => m.Status != "Delete" && m.ProjectId == o.Id.ToString()).Select(m => new InterfaceTree
                {
                    Id = m.Id.ToString(),
                    Name = m.Name,
                    Type = "module",
                    Children = _interfaceQueryService.GetList(i => i.Status != "Delete" && i.ModuleId == m.Id.ToString()).Select(i => new InterfaceTree
                    {
                        Id = i.Id.ToString(),
                        Name = i.Name,
                        Type = "interface",
                        Version = i.Version
                    }).ToList()
                }).ToList()
            }).ToList();
            return CreateResult(project);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [Route("InterfaceTest"), HttpPost, CheckLogin]
        public ApiResult<string> InterfaceTest(InterfaceTest param)
        {
            try
            {
                string response;
                var header = JsonConvert.SerializeObject(param.Header);
                var dic = new Dictionary<string, string>();
                var host = string.Empty;
                if (!string.IsNullOrEmpty(param.Host))
                {
                    host = param.Host;
                }
                if (header != null && header != "{}")
                {
                    dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(header);
                }
                if (param.Method == "POST")
                {
                    var requestParam = param.Param.ToString();
                    if (!param.UseJwt)
                    {
                        requestParam = JsonConvert.SerializeObject(param.Param);
                    }
                    response = HttpUtils.HttpPost(param.Url, requestParam, dic, host);
                }
                else
                {
                    response = HttpUtils.HttpGet(param.Url, dic, host);
                }
                return CreateResult(response);
            }
            catch (Exception e)
            {
                var result = new ApiResult<string>
                {
                    Status = ResultStatus.Error,
                    Message = e.Message,
                    Data = e.Message
                };
                return CreateResult(JsonConvert.SerializeObject(result));
            }
        }
    }
}